package comet

import (
	"acs/comet/config"
	"os"
	"os/signal"
	"runtime"
	"runtime/debug"
	"sync"
	"syscall"
	"time"
)

// exitService 判断服务是否处于退出过程
var exitService = make(chan bool)

// InitSignal register signals handler.
func InitSignal() (c chan os.Signal, exitSigChan chan bool) {
	c = make(chan os.Signal, 1)
	signal.Notify(c)
	return c, exitService
}

// HandleSignal fetch signal from chan then do exit or reload.
func HandleSignal(c chan os.Signal) {
	// Block until a signal is received.
	for {
		s := <-c
		switch s {
		case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
			logger.Infof("received stop sevice signal: %s", s)
			close(exitService)
			return
		case syscall.SIGUSR1:
			logger.Info("start gc and releasing mem...")
			runtime.GC()
			debug.FreeOSMemory()
			logger.Info("gc and releasing mem done.")
		case syscall.SIGHUP:
			// reload
		case syscall.SIGUSR2:
			// show gc stats
			gcStats := new(debug.GCStats)
			memStats := new(runtime.MemStats)
			runtime.ReadMemStats(memStats)
			debug.ReadGCStats(gcStats)
			logger.Infof("GC stats: %+v", *gcStats)
			logger.Infof("Mem stats: %+v", *memStats)
			logger.Infof("Current go routine numbers: %v", runtime.NumGoroutine())
		default:
			// show configs
			logger.Infof("Server running with configurations: %+v\nCurrent go routines: %v", *config.Conf, runtime.NumGoroutine())

			logger.Infof("received un-handlable signal[%s], ignored.", s)
		}
	}
}

func WaitForExit(wg *sync.WaitGroup) {
	<-exitService
	time.Sleep(time.Millisecond * 50)
	wg.Wait()
}
